/*
 * HashFile.h
 *
 *  Created on: Oct 18, 2012
 *      Author: Federico Orquera
 *
 *  Clase que realiza el manejo en archivos de las estructuras del hash.
 *
 */

#ifndef HASHFILE_H_
#define HASHFILE_H_

#include <memory>
#include <cstring>
#include <cassert>

#include "../../physical_layer/FixedSizeBlockFile.h"

#include "HashBucket.h"
#include "HashBucketSerializer.h"
#include "DispersionTable.h"
//#include "archivoDirecto.h"

#define _CONTROL_BLOCK_NBR 0

class DispersionTable;
//class archivoDirecto;
typedef std::shared_ptr<DispersionTable> dispTable_ptr;
typedef std::shared_ptr<HashBucket> bucket_ptr;

class HashFile
{
private:

    typedef size_t HashIndex;
    typedef physical::byteStream controlBlock_t;

    static HashBucketSerializer bucketSerializer;
    static const std::ios_base::openmode blockFileDefaultOpenMode;
    static const size_t minimumControlDataSize;

    size_t m_blockSize;
    physical::FixedSizeBlockFile m_hashFile;

public:
    HashFile(const std::string &filename, size_t blockSize = 0, bool forceTrunc = false );
    virtual ~HashFile();

    void getDispersionTable( HashBucket::TypeTD* &table, HashIndex &tableSize );
    void saveDispersionTable( HashBucket::TypeTD *table, HashIndex tableSize );

    bucket_ptr getNewBucket( HashBucket::TypeTD );
    bucket_ptr getBucket( HashBucket::BucketID bucketNr );
    void saveBucket( bucket_ptr& bucket );

private:
    void parseHeader(const std::string &filename, bool &fileExists );
    void writeHeader();
    physical::UP_byteStream getControlBlock();
    void writeControlBlock( physical::UP_byteStream controlBlock );
};

#endif /* HASHFILE_H_ */
